package picobot.gui;

import java.awt.GridLayout;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import picobot.interfaces.core.ISimulator;

/**
 * a class to represent a Panel where picobots visually move
 */
public class PicoPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3811444357178060573L;

	private PicobotUserInterface pui;
	private JLabel[][] fields;
	private PicoUtility picoUtil = new PicoUtility("setDefault");

	private Icon iconWall = new ImageIcon(picoUtil.getIconWall());
	private Icon iconFree = new ImageIcon(picoUtil.getIconFree());
	private Icon iconBot = new ImageIcon(picoUtil.getIconBot());
	private Icon iconVisited = new ImageIcon(picoUtil.getIconVisited());

	/**
	 * sets the icon for the wall
	 * 
	 * @param iconWall
	 *            the iconWall to set
	 */
	public void setIconWall(Icon iconWall) {
		this.iconWall = iconWall;
	}

	/**
	 * sets the icon for the free cell
	 * 
	 * @param iconFree
	 *            the iconFree to set
	 */
	public void setIconFree(Icon iconFree) {
		this.iconFree = iconFree;
	}

	/**
	 * sets the icon for the bot
	 * 
	 * @param iconBot
	 *            the iconBot to set
	 */
	public void setIconBot(Icon iconBot) {
		this.iconBot = iconBot;
	}

	/**
	 * sets the icon for the visited cell
	 * 
	 * @param iconVisited
	 *            the iconVisited to set
	 */
	public void setIconVisited(Icon iconVisited) {
		this.iconVisited = iconVisited;
	}

	/**
	 * Setup a panel with a given PicobotUserInterface.
	 * 
	 * @param pui
	 *            is the PicobotUserInterface
	 */
	public PicoPanel(PicobotUserInterface pui) {
		this.pui = pui;
		ISimulator simulator = pui.getSimulator();

		int height = simulator.getMap().getHeight();
		int width = simulator.getMap().getWidth();

		setLayout(new GridLayout(height, width, 0, 0));
		fields = new JLabel[height][width];

		for (int y = height - 1; y >= 0; y--) {
			for (int x = 0; x < width; x++) {
				JLabel field = new JLabel(whatIcon(x, y));
				this.add(field);
				fields[y][x] = field;
			}
		}

	}

	/**
	 * This method sets up the images we need for our user interface
	 */
	public void setUpImages() {
		setIconWall(new ImageIcon(picoUtil.getIconWall()));
		setIconFree(new ImageIcon(picoUtil.getIconFree()));
		setIconBot(new ImageIcon(picoUtil.getIconBot()));
		setIconVisited(new ImageIcon(picoUtil.getIconVisited()));
	}

	/**
	 * a method to find the appropriate cell for i given cell
	 * 
	 * @param x
	 *            is the x coordinate of the cell
	 * @param y
	 *            is the y coordinate of the cell
	 * @return the icon that is suitable for the given cell
	 */
	public Icon whatIcon(int x, int y) {
		Icon appropriate = iconFree;
		ISimulator simulator = pui.getSimulator();

		// if the picobot is at the given position
		if ((simulator.getPicobot().getXCoordinate() == x)
				& (simulator.getPicobot().getYCoordinate() == y)) {
			appropriate = iconBot;
		} else {
			// if the position is a wall
			if (simulator.getMap().getCellKind(x, y).equals("WALL")) {
				appropriate = iconWall;
			} else {
				// if the cell is traversed
				int[] cell = { x, y };
				if (PicoUtility.isArrayInSet(simulator.getTraversedCells(),
						cell)) {
					appropriate = iconVisited;
				} else {
					// only possibility left is free
					appropriate = iconFree;
				}
			}
		}
		return appropriate;
	}

	/**
	 * applies a step and updates the images
	 */
	public void stepUpdate() {
		int x = pui.getSimulator().getPicobot().getXCoordinate();
		int y = pui.getSimulator().getPicobot().getYCoordinate();

		fields[y][x].setIcon(iconVisited);

		pui.getSimulator().step();

		int x1 = pui.getSimulator().getPicobot().getXCoordinate();
		int y1 = pui.getSimulator().getPicobot().getYCoordinate();

		fields[y1][x1].setIcon(iconBot);

		// pui.screenAdjustment();

	}

	/**
	 * updates all the images of the panel it is used for reseting a panel
	 */
	public void panelReset() {
		int height = pui.getSimulator().getMap().getHeight();
		int width = pui.getSimulator().getMap().getWidth();

		for (int y = height - 1; y >= 0; y--) {
			for (int x = 0; x < width; x++) {
				fields[y][x].setIcon(whatIcon(x, y));
			}
		}
	}

	/**
	 * changes the skin of a panel, i.e. the icon of the cells
	 * 
	 * @param path
	 *            is the URI path of the skin folder
	 */
	public void changeSkin(String path) {
		picoUtil.setNewSkin(path);
		setUpImages();

	}
}
